#include <dm/os/db/db_pg.hpp>
#include <dm/string/stringlist.hpp>
#include <dm/os/db/resultset_pg.hpp>

namespace dm{
namespace os{

static const char* logModule = "CDbPg.os.dm";

CDbPg::CDbPg( const char* dbName,const char* host ):CDb(dbName,host){
	m_con = NULL;
}

CDbPg::~CDbPg(){
	if( m_con!=NULL )
		PQfinish(m_con);
}

CDb::EDbType CDbPg::dbType(){
	return DtPg;
}

bool CDbPg::isConnected(){
	if( m_con!=NULL )
		return PQstatus(m_con)==CONNECTION_OK;
	return false;
}

bool CDbPg::connect( const char* user,const char* pw ){
    if( m_con )
        PQfinish(m_con);
    dm::string::CStringList slist;
    slist.split(m_host.c_str(),':');

    m_con = PQsetdbLogin(slist.at(0).c_str(),slist.size()>1?slist.at(1).c_str():NULL,NULL,NULL,m_dbName.c_str(),user,pw);		

	return isConnected();
}

void CDbPg::disconnect( ){
    if( m_con ){
        PQfinish(m_con);
        m_con = NULL;
    }
}

bool CDbPg::exec( const char* sql ){
    if( isConnected() ){
        PGresult* result = PQexec(m_con,sql);
        if( result ){
            if( PQresultStatus(result)==PGRES_COMMAND_OK ){
                PQclear(result);
                return true;
            }
            PQclear(result);
        }
    }    

	return false;
}

CResultSet* CDbPg::query( const char* sql ){
	if( isConnected() ){
        CResultSetPg* rs = new CResultSetPg();

        rs->m_rst = PQexec(m_con,sql);
        if( rs->m_rst ){
            rs->m_r = -1;
            if( PQresultStatus(rs->m_rst)==PGRES_TUPLES_OK )
                return rs;
        }

        delete rs;
	}

	return NULL;
}

/**
 * 获取匹配字符串表名
 * @param pattern
 * @param rs
 * @return
 */
CResultSet* CDbPg::getTables( const char* pattern ){
	std::string sql = "select table_name from information_schema.tables where table_type='BASE TABLE' and table_name like '";
	sql += pattern;
	sql += "'";

	return query(sql.c_str());
}

}
}